package com.baofu.paycore.biz.paycore.handler.impl;

import com.baofu.account.service.facade.model.request.UnFreezeReqDTO;
import com.baofu.clear.service.facade.model.resp.NotifyDTO;
import com.baofu.paycore.biz.engine.result.CommandResult;
import com.baofu.paycore.biz.external.account.AccountService;
import com.baofu.paycore.biz.external.account.converter.AccountRequestConverter;
import com.baofu.paycore.biz.model.BackPayBO;
import com.baofu.paycore.biz.paycore.converter.BO2BOConverter;
import com.baofu.paycore.biz.paycore.handler.BaseHandler;
import com.baofu.paycore.common.exception.PayCoreBizException;
import com.baofu.paycore.manager.model.AccountRespBO;
import com.baofu.paycore.manager.model.FreezeBO;
import com.baofu.paycore.manager.model.ResponseBO;
import com.baofu.paycore.manager.model.preAuth.PreAuthBO;
import com.baofu.paycore.manager.model.preAuth.SubPreAuthBO;
import com.baofu.paycore.manager.storer.FreezeOrderRepository;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.baofu.paycore.service.facade.enums.PayStatusEnums;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * </p>
 * User:ames wang  Date: 2017/6/22
 */
@Slf4j
@Service
public class UnfreezeHandler extends BaseHandler<FreezeBO,NotifyDTO> {

    @Autowired
    private FreezeOrderRepository freezeOrderRepository;

    @Autowired
    private AccountService accountService;

    @Override
    public FreezeBO activeOrder(String orderId) {
        FreezeBO freezeBO = freezeOrderRepository.load(orderId);
        if(freezeBO == null){
            log.error("找不到冻结订单:{}",orderId);
            throw new PayCoreBizException(PayCoreErrorCode.ORDER_IS_NOT_EXISTED);
        }
        return freezeBO;
    }

    @Override
    public FreezeBO queryOrderByPayNo(String payNo) {
        return activeOrder(payNo);
    }

    @Override
    protected void checkBeforeProcess(FreezeBO order) {

    }

    @Override
    protected void processOrders(FreezeBO order) {
        accountUnfreeze(order);
        order.setRealFlag(true);
    }

    @Override
    protected void reStore(FreezeBO order) {
        if(PayStatusEnums.SUCCESS.getCode().equals(order.getStatus())){
            freezeOrderRepository.updateUnfreeze(order);
            return;
        }
        freezeOrderRepository.update(order);
    }

    @Override
    protected void processAfter(FreezeBO order, Map<String, CommandResult> cmdResult) {

    }

    /**
     * 提现处理
     *
     * @param freezeBO    提现参数
     * @return              返回值
     */
    @Override
    public BackPayBO process(FreezeBO freezeBO) {
        log.debug("解冻开始处理：{}", freezeBO);
        doExecute(freezeBO);
        log.info("解冻完成结果：{}",freezeBO);
        return BO2BOConverter.freezeBO2BackPayBO(freezeBO);
    }

    /**
     * 账务解冻
     *
     * @param freezeBO        冻结单
     * @return                  true:冻结成功;false:冻结失败
     */
    private void accountUnfreeze(FreezeBO freezeBO) {

        UnFreezeReqDTO unFreezeReqDTO = AccountRequestConverter.getUnFreezeReqDTO(freezeBO);
        AccountRespBO accountRespBO = accountService.unFreeze(freezeBO.getPayNo(),
                freezeBO.getServiceCode(), unFreezeReqDTO);
        //状态初始化,所有单状态不做处理
        if (PayStatusEnums.INIT.getCode().equals(accountRespBO.getStatus())){
            freezeBO.setErrorCode(accountRespBO.getErrorCode());
            freezeBO.setErrorMsg(accountRespBO.getErrorMsg());
            return;
        }
        if (PayStatusEnums.SUCCESS.getCode().equals(accountRespBO.getStatus())){
            freezeBO.setStatus(PayStatusEnums.SUCCESS.getCode());
            freezeBO.setUnfreezeReceiptNo(accountRespBO.getReceiptNo());
            freezeBO.setTransDate(accountRespBO.getAccDate());
        }
        //冻结失败,所有单都置失败
        if (PayStatusEnums.FAIL.getCode().equals(accountRespBO.getStatus())) {
            freezeBO.setStatus(PayStatusEnums.FAIL.getCode());
            freezeBO.setErrorCode(accountRespBO.getErrorCode());
            freezeBO.setErrorMsg(accountRespBO.getErrorMsg());
            return;
        }
    }

    /**
     * 需重试接口 对内部资金单的重试（订单状态推进）
     *
     * @param freezeBO  预授权取消订单对象
     * @return ResponseBO
     * @throws RuntimeException 出现异常时表示重试没有成功（子类方法实现中不可捕获异常）
     */
    @Override
    public ResponseBO dalInnerFundProc(FreezeBO freezeBO) throws RuntimeException {
        ResponseBO responseBO = null;
        if (PayStatusEnums.FAIL.getCode().equals(freezeBO.getStatus())||PayStatusEnums.SUCCESS.getCode().equals(freezeBO.getStatus())){
            log.error("重试接口 单号:{}, 冻结单状态:{}", freezeBO.getPayNo(), freezeBO.getStatus());
            return new ResponseBO(freezeBO.getStatus(), freezeBO.getErrorCode(),
                    freezeBO.getErrorMsg(), freezeBO.getPayNo(), freezeBO.isRealFlag());
        }else{
            log.info("预授权取消payNo:{},状态:{},未成功,走整个流程", freezeBO.getPayNo(), freezeBO.getStatus());
            this.processOrders(freezeBO);
            reStore(freezeBO);
            return new ResponseBO(freezeBO.getStatus(), freezeBO.getErrorCode(),
                    freezeBO.getErrorMsg(), freezeBO.getPayNo(), freezeBO.isRealFlag());
        }
    }
}
